#pragma once

#include <functional>
#include <atomic>
#include <sched.h>
#include <mutex>


#include "noncopyable.h"
#include "poller.h"
#include "channel.h"
#include "current_thread.h"

// 事件循环类， 主要包含了两个大模块 Chanel  Poller
class EventLoop : noncopyable{  

public:
    using Functor = std::function<void()>;

    EventLoop();
    ~EventLoop();

    // 开启事件循环
    void loop();
    // 退出事件循环
    void quit();

    TimeStamp pollReturnTime() const {return pollReturnTime_;}

    // 在当前loop中执行
    void runInLoop(Functor cb);
    // 把cb放入队列中，  唤醒loop所在的线程， 执行cb
    void queueInLoop(Functor cb);

    // 唤醒loop所在的线程
    void wakeup();

    void updateChannel(Channel* channel);
    void removeChannel(Channel* channel);
    bool hasChannel(Channel* channel);
    
    bool isInLoopThread() const{ return threadId_ == CurrentThread::tid();}



private:
    void handleRead();  // 唤醒loop
    void doPendingFunctors();
    using ChannelList = std::vector<Channel*>;

    // 原子操作
    std::atomic_bool looping_;
    std::atomic_bool quit_;   // 标识退出loop循环
    
    const pid_t threadId_;     // 记录当前loop线程的id
    TimeStamp pollReturnTime_;       // poll返回发生事件的channels的时间点
    std::unique_ptr<Poller> poller_;         // 真正的执行epoll_wait 的poller

    int wakeupFd_; // 主要作用 当mainloop获取一个新的用户的channel, 通过轮询算法选择一个subloop，通过该成员唤醒subloop处理
    std::unique_ptr<Channel> wakeupChannel_;

    ChannelList activateChannels_;
    Channel* currentActivateChannel_;

    std::atomic_bool callingPendingFunctors_;     // 标志当前的loop是否需要执行回调操作
    std::vector<Functor> pendingFunctors_;      // 执行loop 需要执行的所有回调操作
    std::mutex mutex_;       // 互斥锁 用来保护上面的vector容器 的线程安全操作
};